package com.yyw.gulimall.ware.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yyw.common.constant.ware.enums.PurchaseDetailEnum;
import com.yyw.common.constant.ware.enums.PurchaseEnum;
import com.yyw.common.exception.RRException;
import com.yyw.common.utils.PageUtils;
import com.yyw.common.utils.Query;
import com.yyw.common.utils.R;
import com.yyw.gulimall.ware.dao.PurchaseDao;
import com.yyw.gulimall.ware.dto.UserDto;
import com.yyw.gulimall.ware.entity.PurchaseDetailEntity;
import com.yyw.gulimall.ware.entity.PurchaseEntity;
import com.yyw.gulimall.ware.feign.UserFeign;
import com.yyw.gulimall.ware.service.PurchaseDetailService;
import com.yyw.gulimall.ware.service.PurchaseService;
import com.yyw.gulimall.ware.service.WareSkuService;
import com.yyw.gulimall.ware.vo.PurchaseDoneVo;
import com.yyw.gulimall.ware.vo.PurchaseItemsDto;
import com.yyw.gulimall.ware.vo.PurchaseMergeVo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("purchaseService")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    private final PurchaseDetailService purchaseDetailService;
    private final UserFeign userFeign;
    private final WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        String status = (String) params.get("status");
        if (!StringUtils.isEmpty(key)) {
            wrapper.lambda().and(e -> {
                e.eq(PurchaseEntity::getAssigneeId, key).or().like(PurchaseEntity::getAssigneeName, key)
                        .or().eq(PurchaseEntity::getWareId, key);
            });
        }
        if (!StringUtils.isEmpty(status)) {
            wrapper.lambda().eq(PurchaseEntity::getStatus, status);
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils getUnreceiveList(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PurchaseEntity::getStatus, PurchaseEnum.CREATED.getCode());
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void merge(PurchaseMergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();
        boolean isAssignee = false;
        if (Objects.equals(null, purchaseId) || Objects.equals("0", purchaseId)) {
            // 没有选择采购单，自动生成采购单
            PurchaseEntity purchase = PurchaseEntity.builder()
                    .createTime(new Date())
                    .status(PurchaseEnum.CREATED.getCode())
                    .priority(1)
                    .build();
            this.save(purchase);
            purchaseId = purchase.getId();
        } else {
            // 查询该订单是否被分配
            PurchaseEntity entity = this.getById(purchaseId);
            if (!Objects.equals(null, entity.getAssigneeId()) && !Objects.equals("0", entity.getAssigneeId())) {
                isAssignee = true;
            }
        }
        // 修改副单的信息
        List<Long> items = mergeVo.getItems();
        if (!CollectionUtils.isEmpty(items)) {
            Long finalPurchaseId = purchaseId;
            boolean finalIsAssignee = isAssignee;
            List<PurchaseDetailEntity> collect = items.stream().map(e -> {
                PurchaseDetailEntity detailEntity = PurchaseDetailEntity.builder()
                        .purchaseId(finalPurchaseId)
                        .status(finalIsAssignee ? PurchaseDetailEnum.ASSIGNED.getCode() : PurchaseDetailEnum.CREATED.getCode())
                        .id(e)
                        .build();
                return detailEntity;
            }).collect(Collectors.toList());
            purchaseDetailService.saveOrUpdateBatch(collect);
        }
    }

    @Override
    public void update(PurchaseEntity purchase) {
        // 判断是否有分配人 否则修改子单状态
        if (!Objects.equals(null, purchase.getAssigneeId())) {
            // 查询子单
            QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(PurchaseDetailEntity::getPurchaseId, purchase.getId());
            List<PurchaseDetailEntity> list = purchaseDetailService.list(wrapper);
            if (!CollectionUtils.isEmpty(list)) {
                // 修改子单状态
                List<PurchaseDetailEntity> collect = list.stream().map(e -> {
                    PurchaseDetailEntity detailEntity = PurchaseDetailEntity.builder()
                            .id(e.getId())
                            .status(PurchaseDetailEnum.ASSIGNED.getCode())
                            .build();
                    return detailEntity;
                }).collect(Collectors.toList());
                purchaseDetailService.updateBatchById(collect);
            }
        }

        // 修改自己
        this.updateById(purchase);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void received(List<Long> ids) {
        // 查询是否已被领取或者是否存在子单
        List<PurchaseEntity> purchaseEntities = this.listByIds(ids);
        if (!CollectionUtils.isEmpty(purchaseEntities)) {
            // 获取当前登录用户信息
            R info = userFeign.info();
            String json = JSON.toJSONString(info.get("user"));
            UserDto user = JSON.parseObject(json, UserDto.class);
            List<PurchaseEntity> filters = purchaseEntities.stream().filter(e -> {
                // 判断领取者是否是当前用户
                if (!Objects.equals(user.getUserId(), e.getAssigneeId())) {
                    throw new RRException("ID: " + e.getId() + ",该采购单没有分配您名下，无法领取");
                }
                // 判断是否已被领取
                if (Objects.equals(e.getStatus(), PurchaseEnum.received.getCode())) {
                    throw new RRException("ID: " + e.getId() + ",该采购单已被领取，无法领取");
                }
                return true;
            }).map(e -> {
                PurchaseEntity entity = PurchaseEntity.builder()
                        .id(e.getId())
                        .status(PurchaseEnum.received.getCode())
                        .updateTime(new Date())
                        .build();
                return entity;
            }).collect(Collectors.toList());
            this.updateBatchById(filters);

            // 修改子单状态
            List<Long> resultIds = filters.stream().map(e -> e.getId()).collect(Collectors.toList());
            QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>();
            wrapper.lambda().in(PurchaseDetailEntity::getPurchaseId, resultIds);
            List<PurchaseDetailEntity> list = purchaseDetailService.list(wrapper);
            if (!CollectionUtils.isEmpty(list)) {
                List<PurchaseDetailEntity> detailEntities = list.stream().map(e -> {
                    PurchaseDetailEntity entity = PurchaseDetailEntity.builder()
                            .id(e.getId())
                            .status(PurchaseDetailEnum.received.getCode())
                            .build();
                    return entity;
                }).collect(Collectors.toList());
                purchaseDetailService.updateBatchById(detailEntities);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void done(PurchaseDoneVo purchaseDone) {
        // 标志是否有异常
        boolean isFlag = true;
        for (PurchaseItemsDto item : purchaseDone.getItems()) {
            PurchaseDetailEntity detailEntity = purchaseDetailService.getById(item.getItemId());
            if (Objects.equals(item.getStatus(), PurchaseDetailEnum.HASERROR.getCode())) {
                // 有异常,不入库
                isFlag = false;
                detailEntity.setReason(item.getReason());
            } else {
                // 入库
                wareSkuService.putWare(detailEntity.getSkuId(), detailEntity.getWareId(), detailEntity.getSkuNum());
            }
            // 修改子单信息
            detailEntity.setStatus(item.getStatus());
            detailEntity.setId(item.getItemId());
            purchaseDetailService.updateById(detailEntity);
        }
        ;

        // 修改父单信息
        PurchaseEntity purchaseEntity = PurchaseEntity.builder()
                .id(purchaseDone.getId())
                .status(isFlag ? PurchaseEnum.finish.getCode() : PurchaseEnum.HASERROR.getCode())
                .updateTime(new Date())
                .build();
        this.updateById(purchaseEntity);

    }

}